#include "weighted_resampler.h"
#include "pair_sampler_sorted.h"

#include <algorithm>
#include <vector>
#include <iostream>

struct pair_comp {
	bool operator() (pair<int, double> * i, pair<int, double> * j) { return (i->second > j->second);}
};

bool weighted_resampler::resample_problem(boosting_problem & prob, double * d_t, int & argc, char **& argv, boosting_problem & selected_prob) {
	if(argc < 1) {
		cout << "arguments not sufficient!" << endl;
		return false;
	}

	int size = atoi(argv[0]);
	argc --;
	argv ++;


	int l = prob.l;

//	selected_prob.l = size;
	selected_prob.dim = prob.dim;
	selected_prob.y = new double[size];
	selected_prob.x = new boosting_node *[size];

	int selected_size = weighted_resample(prob.y, prob.x, l, d_t, size, selected_prob.y, selected_prob.x);
	selected_prob.l = selected_size;
	return true;
}

void weighted_resampler::destroy_problem(boosting_problem & prob) {
	delete [] prob.y;
	delete [] prob.x;
}

int weighted_resampler::weighted_resample(double * y, boosting_node ** x, int l, double * d, int size, double * yo, boosting_node ** xo) {
	vector<pair<int, double> *> pair_list;
	pair_list.resize(l);
	
	for(int i =0; i < l; i++) {
		pair<int, double> * p = new pair<int, double>();
		p->first = i;
		p->second = d[i];
		pair_list[i] = p;
	}

	pair_comp pc;
	sort (pair_list.begin(), pair_list.end(), pc);

	vector<int> selected_list;
	pair_sampler_sorted * ps_sorted = get_pair_sampler_sorted();
	ps_sorted->select_indice(pair_list, selected_list, size);
	delete ps_sorted;

	for(int i = 0; i < l; i++) {
		delete pair_list[i];
	}

	if(selected_list.size() != size) {
		cout << "not enough samples. ";
	}

	sort(selected_list.begin(), selected_list.end());

	for(unsigned i = 0; i < selected_list.size(); i++) {
		int index = selected_list[i];
		yo[i] = y[index];
		xo[i] = x[index];
	}

	return selected_list.size();
}

pair_sampler_sorted * weighted_resampler::get_pair_sampler_sorted() {
	return new pair_sampler_sorted();
}

pair_sampler_sorted * weighted_once_resampler::get_pair_sampler_sorted() {
	return new pair_sampler_sorted_once();
}
